import BooleanField from "./BooleanField";
import CascaderField from "./CascaderField";
import CheckboxField from "./CheckboxField";
import DateField from "./DateField";
import DatetimeField from "./DatetimeField";
import IpField from "./IpField";
import MultiSelectField from "./MultiSelectField";
import NumberField from "./NumberField";
import NumberWithUnitField from "./NumberWithUnitField";
import PasswordField from "./PasswordField";
import RadioField from "./RadioField";
import React from "react";
import SelectField from "./SelectField";
import StringField from "./StringField";
import SwitchField from "./SwitchField";
import TagField from "./TagField";
import TextareaField from "./TextareaField";
import UrlArrayField from "./UrlArrayField";
import UrlField from "./UrlField";

import {
  isUrl,
  isIPv4,
  isIPv6,
  isUndefined,
  isNil,
  isDef,
} from "@ct0/functions";

import validator, { extendValidator } from "../validator";

import type {
  FieldBaseType,
  CustomFieldComponent,
  FormViewValidate,
} from "../type";

export default render;
export { extendField };

const FieldInstance: Record<string, CustomFieldComponent> = {};

function render<FIELD extends FieldBaseType = FieldBaseType>({
  field,
  index,
  isValid,
  showError,
  onChange,
}: {
  field: FIELD;
  index: number;
  isValid: boolean;
  showError: boolean;
  onChange: (index: number, v: any) => void;
}) {
  const Custom = FieldInstance[field.type];

  if (Custom) {
    const handler = (v: any) => {
      onChange(index, v);
      field.onChange?.(v, validator(field, v)[0]);
    };
    return (
      <Custom
        isValid={isValid}
        field={field}
        showError={showError}
        onChange={handler}
      />
    );
  }
  return <>无法渲染: {JSON.stringify(field)}</>;
}

function extendField(
  type: string,
  component: CustomFieldComponent,
  validate?: FormViewValidate<any>
) {
  if (FieldInstance[type])
    throw Error(`FormView[${type}] 已存在, 无法重复添加`);
  FieldInstance[type] = component;
  if (validate) extendValidator(type, validate);
}

extendField("string", StringField, (value: string, { meta }) => {
  if (meta?.min && value.length < meta.min)
    return { isValid: false, errmsg: `内容长度不能少于 ${meta.min}` };
  if (meta?.max && value.length > meta.max)
    return { isValid: false, errmsg: `内容长度不能大于 ${meta.max}` };
});

extendField("number", NumberField, (value: number, { meta }) => {
  if (isDef(meta?.min) && value < meta!.min)
    return { isValid: false, errmsg: `内容不能小于 ${meta!.min}` };
  if (isDef(meta?.max) && value > meta!.max)
    return { isValid: false, errmsg: `内容不能大于 ${meta!.max}` };
});

extendField("boolean", BooleanField);

extendField("url", UrlField, (value: string) => {
  if (!isUrl(value)) return { isValid: false, errmsg: "这不是一个 url" };
});

extendField("radio", RadioField);

extendField("checkbox", CheckboxField, (value: Array<any>, { meta }) => {
  if (meta?.min && value.length < meta.min)
    return { isValid: false, errmsg: `请最少选择${meta.min}项` };
});

extendField("switch", SwitchField);

extendField("password", PasswordField, (value: string, { meta }) => {
  if (meta?.min && value.length < meta.min)
    return { isValid: false, errmsg: `密码长度不能少于 ${meta.min}` };
  if (meta?.max && value.length > meta.max)
    return { isValid: false, errmsg: `密码长度不能大于 ${meta.max}` };
  if (meta?.needNumber && !/\d/.test(value))
    return { isValid: false, errmsg: "密码需要包含数字" };
  if (meta?.needLowercase && !/[a-z]/.test(value))
    return { isValid: false, errmsg: "密码需要包含小写字母" };
  if (meta?.needUppercase && !/[A-Z]/.test(value))
    return { isValid: false, errmsg: "密码需要包含大写字母" };
  if (meta?.needSpecialCharacter && !/[^a-zA-Z0-9]/.test(value))
    return { isValid: false, errmsg: "密码需要包含特殊字符" };
});

extendField("select", SelectField);

extendField("url_array", UrlArrayField, (value: Array<string>) => {
  for (const i of value)
    if (!isUrl(i)) return { isValid: false, errmsg: "不能包含非 url 数据" };
});

extendField("textarea", TextareaField);
extendField("multi_select", MultiSelectField);
extendField("cascader", CascaderField);
extendField("date", DateField);
extendField("datetime", DatetimeField);
extendField("tag", TagField);
extendField("ip", IpField, (value: string, { meta }) => {
  const { ipv4 = true, ipv6 = true } = meta || {};
  if ((ipv4 && isIPv4(value)) || (ipv6 && isIPv6(value))) return;
  else return { isValid: false, errmsg: "IP 格式不正确" };
});
extendField(
  "number_with_unit",
  NumberWithUnitField,
  (value: { value?: number; unit?: string }, { required, meta }) => {
    if (required) {
      if (isNil(value?.value))
        return { isValid: false, errmsg: "内容不能为空" };
      if (isNil(value?.unit)) return { isValid: false, errmsg: "单位不能为空" };
    }
    if (meta?.min && !isUndefined(value.value) && value.value < meta.min)
      return { isValid: false, errmsg: `内容不能小于 ${meta.min}` };
    if (meta?.max && !isUndefined(value.value) && value.value > meta.max)
      return { isValid: false, errmsg: `内容不能大于 ${meta.max}` };
  }
);

// extendField("date_range", DateRangeField);
// extendField("datetime_range", DatetimeRangeField);
